//
//  YWScanQRCodeController.m
//  YWPhotoEditMaster
//
//  Created by jun peng on 2023/9/6.
//

#import "YWScanQRCodeController.h"
#import <AVFoundation/AVFoundation.h>

@interface YWScanQRCodeController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *toBottom;
@property (weak, nonatomic) IBOutlet UIView *scanBackView;

@property (weak, nonatomic) IBOutlet UIImageView *chongjiboImageView;

@property(nonatomic,strong)AVCaptureSession *session; //要把session指着保存下来

@property(nonatomic,weak)AVCaptureVideoPreviewLayer *layer; //绘框的时候需要用到图层所以要指着保存下来

@end

@implementation YWScanQRCodeController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self startScan];
    
}


-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    
    [self startScanAnimation];
    
}

-(void)startScanAnimation{
    
    self.toBottom.constant = self.scanBackView.height;
    [self.view layoutIfNeeded];
    self.toBottom.constant = -self.scanBackView.height;
    [UIView animateWithDuration:1 animations:^{
        
        [UIView setAnimationRepeatCount:MAXFLOAT];
        [self.view layoutIfNeeded];
    }];
    
}

-(void)startScan{
    
    //1、设置输入
    //1.1、获取摄像头设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    //1.2、把摄像头设备当做输入设备 (设备输入)
    NSError *error = nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    
    //2、设置输出 （元数据输出）
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    //3、创建会话，连接输入和输出
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    if([session canAddInput:input] && [session canAddOutput:output]) {//不是所有的输入输出都能添加进来所以要判断
        
        //会话添加输入输出
        [session addInput:input];
        [session addOutput:output];
    }
    else{
        return;
    }
    self.session = session;
    
    //3.1、设置二维码可以识别的码制 （放在output add在session后面、不然会崩）
//    output.metadataObjectTypes = output.availableMetadataObjectTypes; //这个是任何可以识别的东西都能识别
    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode]; // 二维码 //AVMetadataObjectTypeFace
//    output.metadataObjectTypes = @[AVMetadataObjectTypeFace]; // 人面 //AVMetadataObjectTypeFace
    
    //设置扫描的兴趣区域
    //CGRectMake(0, 0, 1, 1) 0.0~1.0
    //它的坐标系是先把手机的头向左倒置地横向摆放、然后再以左上角为坐标（0,0）
    CGRect bounds = self.view.bounds;
    CGFloat x = self.scanBackView.x*1.0/bounds.size.width;
    CGFloat y = self.scanBackView.y*1.0/bounds.size.height;
    CGFloat w = self.scanBackView.width*1.0/bounds.size.width;
    CGFloat h = self.scanBackView.height*1.0/bounds.size.height;
    output.rectOfInterest = CGRectMake(y, x, h, w);
    
    
    
    //3.2、添加视频预览图层、让用户可以看到界面（但不是必须添加只是为了用户友好）
    AVCaptureVideoPreviewLayer *layer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    [self.view.layer insertSublayer:layer atIndex:0];
    layer.frame = self.view.layer.bounds;
    self.layer = layer;
    
    //4、启动会话，让输入开始采集数据、输出对象、开始处理数据
//    dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
//        [session startRunning];
//    });
    
    [session startRunning];
    
}
- (void)dealloc{
//    dispatch_async(dispatch_get_global_queue(0, 0), ^{
//
//        [self.session stopRunning];
//    });
    
    [self.session stopRunning];
}


//扫描到结果之后调用
-(void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    
    /*
//    YWLog(@"%@",metadataObjects.description); //stringValue、corners、bounds、faceID有用
    //二维码结果格式：
//    (
//        "<AVMetadataMachineReadableCodeObject: 0x28177e260,\
//        type=\"org.iso.QRCode\",\
//        bounds={ 0.6,0.3 0.0x0.1 }>\
//        corners { 0.6,0.4 0.6,0.4 0.6,0.3 0.6,0.3 },\
//        time 350751084515375, \
//        stringValue \"I love you.\"",
//    )
    //人面结果格式：AVMetadataFaceObject
//    (
//        "<AVMetadataFaceObject: 0x280d685e0, faceID=1, bounds={0.3,0.6 0.1x0.1}, rollAngle=268.0, yawAngle=352.0, time=351286110340791>"
//    )
    
    */
    
    //移除之前添加的二维码框框
    [self removeSubLayersFrame];
    
    //二维码
    for (id obj in metadataObjects) {
        if([obj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]){
            
            //转换AVMetadataObject的视觉属性到图层坐标
            //转化成为二维码在预览图层上的真正坐标
            AVMetadataObject *resultObj = [self.layer transformedMetadataObjectForMetadataObject:obj];
            
            AVMetadataMachineReadableCodeObject *qrCodeObj = (AVMetadataMachineReadableCodeObject *)resultObj;
            
            YWLog(@"qrCodeObj、stringValue:%@、corners:%@",qrCodeObj.stringValue,qrCodeObj.corners.description);//corners 代表二维码的四个角、但是要借助视频预览图层转化成为我们需要可以用的坐标
           
            //画二维码框框
            [self drawQRCodeFrameWithQRCodeObj:qrCodeObj];
        }
    }
    
    /*
    //人面
    for (id obj in metadataObjects) {
        if([obj isKindOfClass:[AVMetadataFaceObject class]]){
            
            //转换AVMetadataObject的视觉属性到图层坐标
            //转化成为人面在预览图层上的真正坐标
            AVMetadataObject *resultObj = [self.layer transformedMetadataObjectForMetadataObject:obj];
            
            AVMetadataFaceObject *faceObj = (AVMetadataFaceObject *)resultObj;
            
            YWLog(@"faceObj、bounds:%@",NSStringFromCGRect(faceObj.bounds));
            
            //画人面框框
            [self drawfaceObjFrameWithFaceObj:faceObj];
        }
    }
    */
    
}

//- - -- - - - -- -  - --- - --- -

//移除之前添加的二维码框框
-(void)removeSubLayersFrame{
    
    NSArray *subLayers = self.layer.sublayers;
    
    //涉及数组的操作通过倒序遍历不会崩
    [subLayers enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if([obj isKindOfClass:[CAShapeLayer class]]){
            CAShapeLayer *subLayer = (CAShapeLayer *)obj;
            
            [subLayer removeFromSuperlayer];
            
        }
    }];
    
}

//画二维码框
-(void)drawQRCodeFrameWithQRCodeObj:(AVMetadataMachineReadableCodeObject *)qrCodeObj{
    
    NSArray *corners = qrCodeObj.corners;
    
    //1、借助一个图形层来绘制
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
    shapeLayer.fillColor = [UIColor clearColor].CGColor; // 填充颜色要清空
    shapeLayer.strokeColor = [UIColor redColor].CGColor; // 线条的颜色
    shapeLayer.lineWidth = 2; // 线宽
    
    //2、根据四个点来创建一个路径
    UIBezierPath *path = [UIBezierPath bezierPath];
    NSInteger index = 0;
    for (id corner in corners) { //将字典转为CGPoint
        CFDictionaryRef pointDic = (__bridge CFDictionaryRef)corner;
        CGPoint point = CGPointZero;
        CGPointMakeWithDictionaryRepresentation(pointDic, &point);
        
       //根据点一条一条地画pat
        if(index == 0){  //第一个点
            
            [path moveToPoint:point];
        }
        else{
            
            [path addLineToPoint:point];
        }
        index ++;
    }
    
    [path closePath]; //给path封口
    
    //3、给图形图层的路径赋值、代表图层展示怎样的形状
    shapeLayer.path = path.CGPath;
    
    //4、直接添加图形图层到需要展示的图层
    [self.layer addSublayer:shapeLayer];
    
}


/*
//画人面框
-(void)drawfaceObjFrameWithFaceObj:(AVMetadataFaceObject *)faceObj{
    
    CGRect bounds = faceObj.bounds;
    
    //1、借助一个图形层来绘制
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
    shapeLayer.fillColor = [UIColor clearColor].CGColor; // 填充颜色要清空
    shapeLayer.strokeColor = [UIColor redColor].CGColor; // 线条的颜色
    shapeLayer.lineWidth = 2; // 线宽
    
    //2、根据矩形来创建一个路径
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:bounds];
    
    //3、给图形图层的路径赋值、代表图层展示怎样的形状
    shapeLayer.path = path.CGPath;
    
    //4、直接添加图形图层到需要展示的图层
    [self.layer addSublayer:shapeLayer];
    
}
*/

// - ---- - - - - - - ---- --  -
-(void)removeScanAnimation{
    
    [self.chongjiboImageView.layer removeAllAnimations];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//    [self removeScanAnimation];
}

@end
